<template>
  <div ref="chartEl" style="height: 100%;width: 100%"></div>
  <component :is="currentComponent" @initFinished="getBuild"></component>
</template>
<script>
import {
  computed,
  defineAsyncComponent,
  defineComponent,
  onMounted,
  ref,
  toRefs
} from "vue";
import {addListener} from "resize-detector";
import {store} from "@/components/chart/common/store";
import * as echarts from 'echarts'
import 'echarts-wordcloud';

export default defineComponent({
  name: 'vue-echarts',
  components: {
    WordcloudChart: defineAsyncComponent(() =>
      import('@/components/chart/components/echart-wordCloud')
    ),
    BarChart: defineAsyncComponent(() =>
      import('@/components/chart/components/echart-bar')
    ),
    PieChart: defineAsyncComponent(() =>
      import('@/components/chart/components/echart-pie')
    ),
    TreeMapChart: defineAsyncComponent(() =>
      import('@/components/chart/components/echart-treemap')
    ),
    LineChart: defineAsyncComponent(() =>
      import('@/components/chart/components/echart-line')
    ),
    StackBarChart: defineAsyncComponent(() =>
      import('@/components/chart/components/echart-stack-bar')
    ),
    MapChart: defineAsyncComponent(() =>
      import('@/components/chart/components/echart-map')
    ),
    RadarChart: defineAsyncComponent(() =>
      import('@/components/chart/components/echart-radar')
    )
  },
  props: {
    workBook: {type: Object}
  },
  setup(props) {
    const {workBook} = toRefs(props)
    const chartEl = ref(null)
    const buildFunc = ref(Function)
    const currentComponent = computed(() => {
      return store.chartDict.find(t => t.id === workBook.value.chartMode).name
    })

    let currentChart
    let initFlag = false
    const params = []
    let _resolve
    const getBuild = (buildFunction) => {
      buildFunc.value = buildFunction
      initFlag = true
      if (_resolve) {
        currentChart = buildFunction(...params);
        if (currentChart) {
          currentChart.resize = () => {
            params[0].resize()
          }
          if (!currentChart.removeChart) {
            currentChart.removeChart = () => {
              params[0].dispose()
            }
          }
        }
        initFlag = false
        _resolve(currentChart)
        _resolve = null
      }
    }

    let tempChartMode
    /**
     * 图表实现方法
     * @param data 数据
     * @param columnFields 列字段
     * @param rowFields 行字段
     * @param chartMode 图表类型
     * @param options 配置项
     */
    const build = (data, columnFields, rowFields, chartMode, options) => {
      return new Promise((resolve, reject) => {
        const chart = echarts.init(chartEl.value, {
          renderer: store.renderer,
          useDirtyRect: store.useDirtyRect
        });
        if (initFlag || tempChartMode == chartMode) {
          currentChart = buildFunc.value(chart, data, columnFields, rowFields, options, echarts);
          if (currentChart) {
            currentChart.resize = () => {
              chart.resize()
            }
            if (!currentChart.removeChart) {
              currentChart.removeChart = () => {
                chart.dispose()
              }
            }
          }
          resolve(currentChart)
        } else {
          if (params.length > 0) {
            params.splice(0, params.length);
          }
          params.push(chart, data, columnFields, rowFields, options, echarts)
          _resolve = resolve
        }
        tempChartMode = chartMode
      })
    }

    onMounted(() => {
      addListener(chartEl.value, () => {
        if (currentChart) {
          setTimeout(() => {
            currentChart.resize({
              animation: {
                duration: 1000
              }
            })
          }, 200)
        }
      })
    })

    return {
      chartEl,
      build,
      currentComponent,
      getBuild
    }
  }
})
</script>
